/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package BD;

import Schema.*;
import java.sql.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import main.*;
/**
 *
 * @author qiaob
 */
public class BDCommun {
    static final String CONN_URL = "jdbc:oracle:thin:@hopper.e.ujf-grenoble.fr:1521:ufrima";
    static Connection conn = null;
    static final String USER = "favreaur";
    static final String PASSWD = "bd2011";

    public static Connection getConn()  {
        try {
            // Enregistrement du driver Oracle
            System.out.print("Loading Oracle driver... ");
            DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
            System.out.println("loaded");
            // Etablissement de la connection
            System.out.print("Connecting to the database... ");
            conn = DriverManager.getConnection(CONN_URL, USER, PASSWD);
            conn.setAutoCommit(false);
            System.out.println("connected");
        return conn;
        } catch (SQLException ex) {
            Logger.getLogger(BDCommun.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }    
    

    public static void closeConn()  {
        try {
            conn.close();
        } catch (SQLException ex) {
            Logger.getLogger(BDCommun.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public static void valider() {    
        try {
            conn.commit();
        } catch (SQLException ex) {
            Logger.getLogger(BDCommun.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public static void annuler() {
        try {
            conn.rollback();
        } catch (SQLException ex) {
            Logger.getLogger(BDCommun.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    public ResultSet exeQuery(String sql) {
    
    Statement requete = null;
        try {
            requete = conn.createStatement();
            
            return requete.executeQuery(sql); 
        } catch (SQLException ex) {
            Logger.getLogger(BDCommun.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }    
    }
    public static void Serializable(){
        try {
            conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
        } catch (SQLException ex) {
            Logger.getLogger(BDCommun.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    public static void ReadCommitted(){
        try {
            conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
        } catch (SQLException ex) {
            Logger.getLogger(BDCommun.class.getName()).log(Level.SEVERE, null, ex);
        }
    
    }
    
      /**
    *  La suppression d'une commande a l'aide d'une commande donne
    *  @param  c  l'instance Commande qu'on veut supprimer
    *  @exception  les exceptions gener pendant la suppression
    *  @return vide sans retour  
    */
  
public void SuppressionCommande(Commande c) {
//annulation de la commande elle même
  if ( c.getStatutCom().equals("en cours")){
            try {
                c.setStatutCom("annule");
               
                PreparedStatement stmt1=conn.prepareStatement("UPDATE Commande SET statutCom=? WHERE IdCommande=?");
                stmt1.setString(1, c.getStatutCom());
                stmt1.setInt(2, c.getIdCommande());
                stmt1.executeUpdate();
                stmt1.close();
                //annulation de la livraison de chaque article de la commande
                PreparedStatement stmt=conn.prepareStatement("select IdLivraison,IdCommande from Article where IdCommande=?");
                stmt.setInt(1, c.getIdCommande());
                ResultSet resultat= stmt.executeQuery();
                System.out.println("");
                while(resultat.next()) {
                  //Mise a jour de chaque livraison des articles selectionnés precedement
                  PreparedStatement stmt2=conn.prepareStatement("UPDATE Livraison SET StatutLiv=? WHERE IdLivraison=?");
                  stmt2.setString(1, "annule");
                  stmt2.setInt(2, resultat.getInt("IdLivraison"));
                  stmt2.executeUpdate();
                  stmt2.close();
                }
                stmt.close();
                resultat.close();
                this.valider();
            } catch (SQLException ex) {
                Logger.getLogger(BDCommun.class.getName()).log(Level.SEVERE, null, ex);
                this.annuler();
            }
  }
  if (c.getStatutCom().equals("envoi partiel")){
            try {
                int prix=0;
                //annulation de la livraison de chaque article de la commande qui n'a pas encore été envoyés
                PreparedStatement stmt=conn.prepareStatement("select a.IdLivraison,a.IdCommande,a.Quantite, a.PrixUnitaire from Article a,Livraison l where a.IdLivraison=l.IdLivraison and a.IdCommande=? and l.StatutLiv=?");
                stmt.setInt(1, c.getIdCommande());
                stmt.setString(2, "en cours");
                ResultSet resultat= stmt.executeQuery();
                System.out.println("");
                while(resultat.next()) {
                  //Mise a jour de chaque livraison des articles pas encore envoyés selectionnés precedement
                  PreparedStatement stmt2=conn.prepareStatement("UPDATE Livraison SET StatutLiv=? WHERE IdLivraison=?");
                  stmt2.setString(1, "annule");
                  stmt2.setInt(2, resultat.getInt("a.IdLivraison"));
                  stmt2.executeUpdate();
                  stmt2.close();
                  //On recupere le prix de l'article que l'on annule pour mettre a jour le prix total de la commande
                  int qte=resultat.getInt("a.Quantite");
                  double pu=resultat.getDouble("a.PrixUnitaire");
                  prix+=qte*pu;
                }
                stmt.close();
                resultat.close();
                //Mise a jour du prix total de la commande
                double tot=c.getPrixTotal()-prix;
                PreparedStatement stmt1=conn.prepareStatement("UPDATE Commande SET prixTotal=? WHERE IdCommande=?");
                stmt1.setDouble(1, tot );
                stmt1.setInt(2, c.getIdCommande());
                stmt1.executeUpdate();
                stmt1.close();
                this.valider();
                System.out.println("Suppression partielle de la commande, les articles qui n'avaient pas encore été envoyés ont été annulés");
            } catch (SQLException ex) {
                Logger.getLogger(BDCommun.class.getName()).log(Level.SEVERE, null, ex);
                this.annuler();
            }
  }
  if ( c.getStatutCom().equals("envoi complet")){
    System.out.println("Suppression de la commande impossible car elle a déjà été envoyée");
  }
  // Commit

}   

   /**
     *  Modifier le partage de fichier selon un parametre donne
     *  @param f     l'instance objet Fichier donner a modifier
     *  @param p     le droit d'access qu'on veut attacher
     *  @exception  les exceptions genere pendant la consultation ,ou bien les insertions
     *  @return  vide   sans retour
     */    
    public void modifierPartageFichier(Fichier f, String p) {

        if (!f.getPartage().equals(p)) {
            if (p.equals("O")) {
                try {
                    //Parametrer une requete
                    Statement requete = conn.createStatement();
                    String sql = "UPDATE Fichier SET partage='" + p + "' WHERE Fid=" + f.getFid();
                    //Execution de requete
                    int res = requete.executeUpdate(sql);
                    System.out.println("Le partage du fichier: "+f.getFid()+" à été activé");
                } catch (SQLException ex) {
                    annuler();
                    Logger.getLogger(BDClient.class.getName()).log(Level.SEVERE, null, ex);
                }
            } else
            {   try {
                    ResultSet rst=this.exeQuery("select fi.Fid,ph.NumPhoto,art.IdCommande,art.IdAlbum,art.IdFormat from Fichier fi , Photo ph,Album a, Livraison l ,Article art where fi.Fid = ph.Fid AND ph.IdAlbum= a.IdAlbum AND a.IdCli=fi.IdCli AND ph.IdAlbum=art.IdAlbum AND art.IdLivraison=l.IdLivraison AND l.statutLiv!='envoye' and fi.FId="+f.getFid());
                   
                    if(!rst.next()){
                        //Parametrer une requete
                        Statement requete = conn.createStatement();
                        String sql = "UPDATE Fichier SET partage='" + p + "' WHERE Fid=" + f.getFid();
                        //Execution de requete
                        int res = requete.executeUpdate(sql);
                         System.out.println("Le partage du fichier: "+f.getFid()+" à été désactivé");
                        
                    } else {
                        while (rst.next()) {
                         //Parametrer une requete
                          Statement requete1 = conn.createStatement();
                          String sql1 = "UPDATE Fichier SET partage='C' WHERE Fid="+f.getFid();
                         //Execution de requete
                          int res1 = requete1.executeUpdate(sql1);
                        // Insertion d'une trace dans la table temporelle
                          PreparedStatement stmt = conn.prepareStatement("insert into LASupprPartage(FId,NumPhoto,IdAlbum,IdCommande,IdFormat) values (?,?, ?, ?, ?)");
                            stmt.setInt(1,rst.getInt("FId"));
                            stmt.setInt(2,rst.getInt("NumPhoto"));
                            stmt.setInt(3,rst.getInt("IdAlbum"));
                            stmt.setInt(4,rst.getInt("IdCommande"));
                            stmt.setInt(5,rst.getInt("IdFormat"));
                            int rstt=stmt.executeUpdate();  
                          
                        }
                        System.out.println("Le partage du fichier: "+f.getFid()+" en attente de suppression, des albums contenant ce fichier sont en cours d'envoi");
                    }
                    valider();
                } catch (SQLException ex) {
                    annuler();
                    Logger.getLogger(BDCommun.class.getName()).log(Level.SEVERE, null, ex);
                    
                }
            } 
        }
    }
    
    public String SuppressionCodePromo(CodePromo cp, Client cli, Commande c) {
        try {
            this.ReadCommitted();
            PreparedStatement stmt=conn.prepareStatement("insert into BonUtilise (IdCode, IdCommande,IdCli, Reduction) values (?,?,?,?)");
            stmt.setInt(1, cp.getIdCode());
            stmt.setInt(2, c.getIdCommande());
            stmt.setInt(3, cli.getIdCli());
            stmt.setDouble(4, cp.getReduction());
            int resultat= stmt.executeUpdate();
            
            //Suppression du bon de commande de la table bon utilisé puisqu'il a été rendu
            PreparedStatement stmt1=conn.prepareStatement("delete from CodePromo where IdCode=?");
            stmt1.setInt(1, cp.getIdCode());
            int resultat1= stmt1.executeUpdate();
            this.valider();
            return "Le code de promotion "+ cp.getIdCode()+" à été utilisé";
            
        } catch (SQLException ex) {
         
                this.annuler();
                return null;
        }
}
    
    
    
public String SuppressionDefinitiveCodePromo(Commande c, Client cli){
        try {
            PreparedStatement stmt=conn.prepareStatement("select IdCode,reduction from BonUtilise where IdCommande=? and IdCli=?");
            stmt.setInt(1, c.getIdCommande());
            stmt.setInt(2, cli.getIdCli());
            ResultSet resultat= stmt.executeQuery();
            if(resultat.wasNull()){
              return "Aucun bon de commande n'a été utilisé pour cette commande";
            
            }
            else{
            if(c.getStatutCom().equals("envoi complet") || (c.getStatutCom().equals("envoi partiel"))){
                PreparedStatement stmt1=conn.prepareStatement("delete from BonUtilise where IdCode=?");
                stmt.setInt(1, resultat.getInt("IdCode"));
                int resultat1= stmt.executeUpdate();
                return "Le bon de promo est supprime";
              
            }
            if(c.getStatutCom().equals("annule")){
              //Si la commande a été annulée on rend le bon de reduction a son propriétaire
              PreparedStatement stmt1=conn.prepareStatement("insert into CodePromo (IdCode, IdCli, Reduction) values (?,?,?)");
              stmt.setInt(1, resultat.getInt("IdCode"));
              stmt.setInt(2, cli.getIdCli());
              stmt.setDouble(3, resultat.getDouble("reduction"));
              int resultat3= stmt1.executeUpdate();
            
              //Suppression du bon de commande de la table bon utilisé puisqu'il a été rendu
              PreparedStatement stmt2=conn.prepareStatement("delete from BonUtilise where IdCode=?");
              stmt1.setInt(1, resultat.getInt("IdCode"));
              int resultat4= stmt2.executeUpdate();
              this.valider();
             return "La commande à été annulée, le code promo vous a été restituez";
            }
            return null;
            }
        } catch (SQLException ex) {
            Logger.getLogger(BDCommun.class.getName()).log(Level.SEVERE, null, ex);
            this.annuler();
            return null;
        }
}


public boolean suppressionFichier(Fichier f) {

  modifierPartageFichier(f,"N");
  System.out.println("Fichier en attente de suppression");
  ThreadSupprFichier t1 = new ThreadSupprFichier(f, conn);
  t1.start();
        try {
            t1.join();
        } catch (InterruptedException ex) {
            Logger.getLogger(BDCommun.class.getName()).log(Level.SEVERE, null, ex);
        }
  t1.stop();
  valider();
  return true;

}


}
